﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Data;

namespace ALDIOrganizer
{

    public class ListViewItemTag
    {        
        public Int64 employeeID;
        public Int64 month;
        public Int64 timeStatus;

        public Int64 id;
    }

    public class Holiday : IComparable
    {
        internal DataRow row;

        public Holiday(DataRow row)
        {
            this.row = row;            
        }

        public Int64 ID
        {
            get { return row[0] is Int64 ? (Int64) row[0] : -1; }
            set { row[0] = (Int64)value; }
        }

        public Int64 empID
        {
            get { return (Int64)row[1]; }
            set { row[1] = (Int64)value; }
        }

        public DateTime startDate
        {
            get { return (DateTime)row[2]; }
            set { row[2] = (DateTime)value; }
        }

        public DateTime endDate
        {
            get { return (DateTime)row[3]; }
            set { row[3] = (DateTime)value; }
        }

        public HolidayType type
        {
            get { return ((Int64)row[4]).To<HolidayType>(); }
            set { row[4] = (Int64)value; }
        }

        public bool pending
        {
            get { return (bool)row[5]; }
            set { row[5] = (bool)value ? 1 : 0; }
        }

        public string comments
        {
            get { return (row[6] is string) ? (string)row[6] : String.Empty; }
            set { row[6] = (string)value; }
        }

        public string displayColumn
        {
            get { return (row[7] is string) ? (string)row[7] : String.Empty; }
            set { row[7] = (string)value; }
        }

        public override string ToString()
        {
            return displayColumn;
        }

        public string FullDescription()
        {
            return String.Concat(
                startDate.ToLongDateString(),
                " - ",
                endDate.ToLongDateString());
        }

        public string ToShortString()
        {
            switch (type)
            {
                case HolidayType.regular:
                case HolidayType.unpaid:                    
                case HolidayType.paternal:
                case HolidayType.sick:
                    {
                        return type.GetTypeName();
                    }
                case HolidayType.special:
                    {
                        return (comments.Length > Settings.Default.HOLIDAY_SpeciaHolidayl_LengthLimit) ?
                        comments.Substring(0, Settings.Default.HOLIDAY_SpeciaHolidayl_LengthLimit) :
                        comments;
                    }                    
                default:
                    {
                        return String.Empty;
                    }                    
            }
        }

        public static Holiday[] ToHolidays(DataRow[] rows)
        {
            var list = rows.Select(row => new Holiday(row)).ToList();
            list.Sort();
            return list.ToArray();
        }

        public static void DescribeHolidays(Holiday[] holidays)
        {
            if (holidays == null ||
                holidays.Length == 0)
            {
                return;
            }

            foreach (var holiday in holidays)
            {
                holiday.displayColumn = holiday.FullDescription();
            }
        }


        public ListViewItem ToListViewItem(bool coloured)
        {
            #region listview columns
            // EMPLOYEE
            var result = new ListViewItem(SQLiteAccess.GetEmployeeFullName(empID)); // first Name
                        
            // PERIOD
            result.SubItems.Add(startDate.ToShortDateString() + " - " + endDate.ToShortDateString()); // displayColumn / period (eg. 24.04 - 1.05)
            // TOTAL DAYS
            result.SubItems.Add(((endDate - startDate).Days + 1).ToString()); // GetTotal pDays

            // TYPE
            result.SubItems.Add(type.GetTypeName());

            // STATUS
            var statuses = new List<String>();
            var hasBegan = startDate <= DateTime.Now;
            var isOver = endDate < DateTime.Now;
            int timeStatus;
            if (hasBegan)
            {
                timeStatus = isOver ? -1 : 0;
            }
            else
            {
                timeStatus = 1;
            }
            switch (timeStatus)
            {
                case -1:
                    {
                        statuses.Add("finished");
                        break;
                    }
                case 0:
                    {
                        statuses.Add("in progress");
                        break;
                    }
                case 1:
                    {
                        statuses.Add("ahead");
                        break;
                    }
            }
            if (pending)
            {
                statuses.Add("pending");
            }
            result.SubItems.Add(
                String.Join(
                ", ",
                statuses.ToArray()));

            // COMMENTS
            result.SubItems.Add(comments);
            #endregion

            #region Tag which will be used to assign it to groups
            var tag = new ListViewItemTag
                          {
                              employeeID = empID,
                              month = startDate.Month,
                              timeStatus = Convert.ToSByte(timeStatus),
                              id = ID
                          };

            result.Tag = tag;
            #endregion


            result.ForeColor = (pending && coloured) ?
                SystemColors.InactiveCaptionText :
                SystemColors.ControlText;

            return result;
        }

        #region IComparable Members

        public int CompareTo(object obj)
        {
            if (obj.GetType() != this.GetType())
                return default(int);
            var other = obj as Holiday;

            if (this.startDate == other.startDate)
                return this.endDate.CompareTo(other.endDate);
            else
                return this.startDate.CompareTo(other.startDate);
        }

        #endregion
    }



}
